import React, { useState, useEffect, useCallback, useRef } from 'react';
import '../styles/Tetris.css';

const BOARD_WIDTH = 10;
const BOARD_HEIGHT = 20;

const TETROMINOS = {
  I: [
    [1, 1, 1, 1]
  ],
  O: [
    [1, 1],
    [1, 1]
  ],
  T: [
    [0, 1, 0],
    [1, 1, 1]
  ],
  L: [
    [1, 0],
    [1, 0],
    [1, 1]
  ],
  J: [
    [0, 1],
    [0, 1],
    [1, 1]
  ],
  S: [
    [0, 1, 1],
    [1, 1, 0]
  ],
  Z: [
    [1, 1, 0],
    [0, 1, 1]
  ]
};

const Tetris = () => {
  const [board, setBoard] = useState(createEmptyBoard());
  const [currentPiece, setCurrentPiece] = useState(null);
  const [position, setPosition] = useState({ x: 0, y: 0 });
  const [gameOver, setGameOver] = useState(false);
  const [score, setScore] = useState(0);
  const [speed, setSpeed] = useState(1000); // 初始速度1秒
  const [isPaused, setIsPaused] = useState(false);
  const [isDragging, setIsDragging] = useState(false);
  const [panelPosition, setPanelPosition] = useState({ x: 20, y: 20 });
  const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
  const controlsRef = useRef(null);

  function createEmptyBoard() {
    return Array(BOARD_HEIGHT).fill().map(() => Array(BOARD_WIDTH).fill(0));
  }

  const spawnPiece = useCallback(() => {
    const pieces = Object.keys(TETROMINOS);
    const newPiece = TETROMINOS[pieces[Math.floor(Math.random() * pieces.length)]];
    setCurrentPiece(newPiece);
    setPosition({ x: Math.floor((BOARD_WIDTH - newPiece[0].length) / 2), y: 0 });
  }, []);

  const isValidMove = (piece, newX, newY) => {
    for (let y = 0; y < piece.length; y++) {
      for (let x = 0; x < piece[y].length; x++) {
        if (piece[y][x]) {
          const boardX = newX + x;
          const boardY = newY + y;
          
          if (
            boardX < 0 ||
            boardX >= BOARD_WIDTH ||
            boardY >= BOARD_HEIGHT ||
            (boardY >= 0 && board[boardY][boardX])
          ) {
            return false;
          }
        }
      }
    }
    return true;
  };

  const mergePiece = () => {
    const newBoard = board.map(row => [...row]);
    
    for (let y = 0; y < currentPiece.length; y++) {
      for (let x = 0; x < currentPiece[y].length; x++) {
        if (currentPiece[y][x]) {
          if (position.y + y < 0) {
            setGameOver(true);
            return;
          }
          newBoard[position.y + y][position.x + x] = 1;
        }
      }
    }

    // 检查是否有完整的行
    let clearedLines = 0;
    for (let y = BOARD_HEIGHT - 1; y >= 0; y--) {
      if (newBoard[y].every(cell => cell === 1)) {
        newBoard.splice(y, 1);
        newBoard.unshift(Array(BOARD_WIDTH).fill(0));
        clearedLines++;
        y++;
      }
    }

    // 更新分数
    if (clearedLines > 0) {
      setScore(score + clearedLines * 100);
    }

    setBoard(newBoard);
    spawnPiece();
  };

  const moveDown = () => {
    if (currentPiece && !gameOver) {
      if (isValidMove(currentPiece, position.x, position.y + 1)) {
        setPosition(prev => ({ ...prev, y: prev.y + 1 }));
      } else {
        mergePiece();
      }
    }
  };

  const moveLeft = () => {
    if (currentPiece && isValidMove(currentPiece, position.x - 1, position.y)) {
      setPosition(prev => ({ ...prev, x: prev.x - 1 }));
    }
  };

  const moveRight = () => {
    if (currentPiece && isValidMove(currentPiece, position.x + 1, position.y)) {
      setPosition(prev => ({ ...prev, x: prev.x + 1 }));
    }
  };

  const rotatePiece = () => {
    if (!currentPiece) return;

    const rotated = currentPiece[0].map((_, i) =>
      currentPiece.map(row => row[i]).reverse()
    );

    if (isValidMove(rotated, position.x, position.y)) {
      setCurrentPiece(rotated);
    }
  };

  useEffect(() => {
    if (!currentPiece && !gameOver) {
      spawnPiece();
    }
  }, [currentPiece, gameOver, spawnPiece]);

  useEffect(() => {
    const handleKeyPress = (e) => {
      if (gameOver) return;
      if (isPaused && e.key !== 'p') return; // 暂停时只响应 p 键

      switch (e.key) {
        case 'p':
          setIsPaused(prev => !prev);
          break;
        case 'ArrowLeft':
          moveLeft();
          break;
        case 'ArrowRight':
          moveRight();
          break;
        case 'ArrowDown':
          moveDown();
          break;
        case 'ArrowUp':
          rotatePiece();
          break;
        default:
          break;
      }
    };

    window.addEventListener('keydown', handleKeyPress);
    return () => window.removeEventListener('keydown', handleKeyPress);
  }, [currentPiece, position, board, gameOver, isPaused]);

  useEffect(() => {
    if (gameOver || isPaused) return;

    const interval = setInterval(moveDown, speed);
    return () => clearInterval(interval);
  }, [position, speed, gameOver, isPaused]);

  const renderBoard = () => {
    const displayBoard = board.map(row => [...row]);

    if (currentPiece) {
      for (let y = 0; y < currentPiece.length; y++) {
        for (let x = 0; x < currentPiece[y].length; x++) {
          if (currentPiece[y][x] && position.y + y >= 0) {
            displayBoard[position.y + y][position.x + x] = 1;
          }
        }
      }
    }

    return displayBoard.map((row, y) => (
      row.map((cell, x) => (
        <div key={`${y}-${x}`} className={`cell ${cell ? 'filled' : ''}`} />
      ))
    ));
  };

  const handleSpeedChange = (e) => {
    setSpeed(1000 / e.target.value); // 将速度转换为毫秒
  };

  const restartGame = () => {
    setBoard(createEmptyBoard());
    setCurrentPiece(null);
    setGameOver(false);
    setScore(0);
    setSpeed(1000);
  };

  const handleMouseDown = (e) => {
    // 如果点击的是按钮或输入框，不启动拖拽
    if (e.target.tagName.toLowerCase() === 'button' || 
        e.target.tagName.toLowerCase() === 'input') {
      return;
    }
    
    const rect = controlsRef.current.getBoundingClientRect();
    setDragOffset({
      x: e.clientX - rect.left,
      y: e.clientY - rect.top
    });
    setIsDragging(true);
    
    // 防止文本选择
    e.preventDefault();
  };

  const handleMouseMove = useCallback((e) => {
    if (!isDragging) return;

    const newX = e.clientX - dragOffset.x;
    const newY = e.clientY - dragOffset.y;

    // 确保不会拖出屏幕
    const maxX = window.innerWidth - (controlsRef.current?.offsetWidth || 0);
    const maxY = window.innerHeight - (controlsRef.current?.offsetHeight || 0);

    setPanelPosition({
      x: Math.min(Math.max(0, newX), maxX),
      y: Math.min(Math.max(0, newY), maxY)
    });
  }, [isDragging, dragOffset]);

  const handleMouseUp = useCallback(() => {
    setIsDragging(false);
  }, []);

  // 添加和移除事件监听器
  useEffect(() => {
    if (isDragging) {
      window.addEventListener('mousemove', handleMouseMove);
      window.addEventListener('mouseup', handleMouseUp);
    }
    return () => {
      window.removeEventListener('mousemove', handleMouseMove);
      window.removeEventListener('mouseup', handleMouseUp);
    };
  }, [isDragging, handleMouseMove, handleMouseUp]);

  return (
    <div className="tetris-wrapper">
      <div className="tetris">
        {renderBoard()}
      </div>
      <div
        ref={controlsRef}
        className={`game-info ${isDragging ? 'dragging' : ''}`}
        style={{
          transform: `translate(${panelPosition.x}px, ${panelPosition.y}px)`,
          cursor: isDragging ? 'grabbing' : 'grab'
        }}
        onMouseDown={handleMouseDown}
      >
        <div className="score">分数: {score}</div>
        <div className="speed-control">
          速度:
          <input 
            type="range" 
            min="1" 
            max="10" 
            value={1000/speed} 
            onChange={handleSpeedChange}
          />
        </div>
        <div className="game-controls">
          <button onClick={() => setIsPaused(prev => !prev)}>
            {isPaused ? '继续' : '暂停'}
          </button>
          <button onClick={restartGame}>重新开始</button>
        </div>
      </div>
    </div>
  );
};

export default Tetris; 